package org.jetlinks.pro.tenant.impl;

import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils;
import org.jetlinks.pro.assets.AssetBindRequest;
import org.jetlinks.pro.assets.AssetType;
import org.jetlinks.pro.tenant.TenantAssetManager;
import org.jetlinks.pro.tenant.dimension.TenantDimensionType;
import org.jetlinks.pro.tenant.impl.entity.AssetMemberBindEntity;
import reactor.core.publisher.Flux;

import javax.validation.constraints.NotBlank;
import java.util.List;

@Getter
@Setter
@AllArgsConstructor
public class BindAssetsRequest extends AssetBindRequest {

    @NotBlank
    @Schema(description = "用户ID")
    private String userId;

    @Hidden
    private String tenantId;

    public BindAssetsRequest() {
        setTargetType(TenantDimensionType.tenantMember.getId());
    }

    public static BindAssetsRequestBuilder create() {
        return new BindAssetsRequestBuilder();
    }

    public void setUserId(String userId) {
        this.userId = userId;
        super.setTargetId(userId);
    }

    @Override
    public void setTargetId(String targetId) {
        this.userId = targetId;
        super.setTargetId(targetId);
    }


    public Flux<AssetMemberBindEntity> toBindEntity(String tenantId, TenantAssetManager manager) {
        if (CollectionUtils.isEmpty(getAssetIdList())) {
            return Flux.empty();
        }
        return Flux.fromIterable(getAssetIdList())
                   .map(assetId -> {
                       AssetType type = AssetType.of(getAssetType());
                       List<org.jetlinks.pro.assets.AssetPermission> assetPermissions = isAllPermission()
                           ? type.getPermissions()
                           : type.getPermissions(getPermission());

                       AssetMemberBindEntity bindEntity = new AssetMemberBindEntity();
                       bindEntity.setAssetId(assetId);
                       bindEntity.setAssetType(getAssetType());
                       bindEntity.setPermission(type.createPermission(assetPermissions));
                       bindEntity.setUserId(userId);
                       bindEntity.setTenantId(tenantId);
                       bindEntity.setRelation(getRelation());
                       bindEntity.setUpdateTime(System.currentTimeMillis());
                       bindEntity.generateId();
                       return bindEntity;
                   });

    }

    public static class BindAssetsRequestBuilder {
        private @NotBlank String userId;
        private @NotBlank String assetType;
        private List<String> assetIdList;
        private List<String> permission;
        private boolean allPermission;
        private String tenantId;

        BindAssetsRequestBuilder() {
        }

        public BindAssetsRequestBuilder userId(@NotBlank String userId) {
            this.userId = userId;
            return this;
        }

        public BindAssetsRequestBuilder assetType(@NotBlank String assetType) {
            this.assetType = assetType;
            return this;
        }

        public BindAssetsRequestBuilder assetIdList(List<String> assetIdList) {
            this.assetIdList = assetIdList;
            return this;
        }

        public BindAssetsRequestBuilder permission(List<String> permission) {
            this.permission = permission;
            return this;
        }

        public BindAssetsRequestBuilder allPermission(boolean allPermission) {
            this.allPermission = allPermission;
            return this;
        }

        public BindAssetsRequestBuilder tenantId(String tenantId) {
            this.tenantId = tenantId;
            return this;
        }

        public BindAssetsRequest build() {
            BindAssetsRequest request= new BindAssetsRequest();
            request.setUserId(userId);
            request.setAssetType(assetType);
            request.setAssetIdList(assetIdList);
            request.setPermission(permission);
            request.setAllPermission(allPermission);
            request.setTenantId(tenantId);
            return request;
        }

        public String toString() {
            return "BindAssetsRequest.BindAssetsRequestBuilder(userId=" + this.userId + ", assetType=" + this.assetType + ", assetIdList=" + this.assetIdList + ", permission=" + this.permission + ", allPermission=" + this.allPermission + ", tenantId=" + this.tenantId + ")";
        }
    }
}